﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using personalplaner.business.stamm;
using personalplaner.common.mvvm;
using personalplaner.common.mvvm.commands;
using personalplaner.gui.common;
using personalplaner.servicemodel.dataaccess;
using personalplaner.business;

namespace personalplaner.gui.stamm.viewmodels
{
	public class AddDiensteToLayoutViewModel: BaseViewModel
	{
		bool changed;
		
		public AddDiensteToLayoutViewModel(DependencyObject parent)
            : base(parent)
        {
		}

		#region Implementation

		public override void Loaded()
		{
			var mw = GetService<IMainWindowDisplayContainer>();
			mw.IsWaitVisible = false;
		}

		public override void Unload()
		{
			//Abteilungen = null;
			//SelectedAbteilung = null;
			//NotAddedDienste = null;
			//SelectedNotAddedDienst = null;

			//AddedDienste = null;
			//SelectedAddedDienst = null;
		}

		private void Save()
		{
			var da = GetService<IDiensteDataAccess>();
			if(!da.SaveDiensteToSchema(AddedDienste,SchemaID,SelectedAbteilung.AbteilungID))
				MessageBox.Show(Window.GetWindow(Parent), "Beim Speichern der Dienste ist ein Fehler aufgetreten","Fehler beim speichern", MessageBoxButton.OK, MessageBoxImage.Error);
		}

		#endregion

		#region Commands

		ICommand _addToListCommand;
		public ICommand AddToListCommand
		{
			get
			{
				if (_addToListCommand == null)
					_addToListCommand = new RelayCommand(OnAddToList, parameter => SelectedNotAddedDienst != null);
				return _addToListCommand;
			}
		}

		private void OnAddToList(object parameter)
		{
			if (SelectedNotAddedDienst == null)
				return;

			var dienst = SelectedNotAddedDienst;

			if (EinsaetzeProTag <= 0)
			{
				MessageBox.Show("Es muss mindestens 1 Einsatz pro Tag zugewiesen sein", "Kein Einsatz zugewiesen",
				                MessageBoxButton.OK, MessageBoxImage.Asterisk);
				RaiseMoveFocus("EinsaetzeProTag");
				return;
			}

			dienst.EinsatzProTag = EinsaetzeProTag;

			NotAddedDienste.Remove(dienst);
			AddedDienste.Add(dienst);

			EinsaetzeProTag = 1;

			changed = true;
		}

		ICommand _removeFromListCommand;
		public ICommand RemoveFromListCommand
		{
			get
			{
				if (_removeFromListCommand == null)
					_removeFromListCommand = new RelayCommand(OnRemoveFromList, parameter => SelectedAddedDienst != null);
				return _removeFromListCommand;
			}
		}

		private void OnRemoveFromList(object parameter)
		{
			if (SelectedAddedDienst == null)
				return;

			var dienst = SelectedAddedDienst;
			AddedDienste.Remove(dienst);
			
			NotAddedDienste.Add(dienst);
			var lst = (from a in NotAddedDienste
					   orderby a.DienstID ascending
					   select a).ToList();

			NotAddedDienste.Clear();
			foreach (var a in lst)
				NotAddedDienste.Add(a);

			changed = true;
		}

		ICommand _okcommand;
		public ICommand OkCommand
		{
			get
			{
				if (_okcommand == null)
					_okcommand = new RelayCommand(OnOkCommand);
				return _okcommand;
			}
		}

		private void OnOkCommand(object parameter)
		{
			if (changed)
				Save();

			var mw = GetService<IMainWindowDisplayContainer>();
			mw.MoveToPreviousView();
		}

		ICommand _cancelcommand;
		public ICommand CancelCommand
		{
			get
			{
				if (_cancelcommand == null)
					_cancelcommand = new RelayCommand(OnCancelCommand);
				return _cancelcommand;
			}
		}

		private void OnCancelCommand(object parameter)
		{
			var mw = GetService<IMainWindowDisplayContainer>();
			mw.MoveToPreviousView();
		}

        ICommand _savecommand;
        public ICommand SaveCommand
        {
            get
            {
                if (_savecommand == null)
                    _savecommand = new RelayCommand(OnSaveCommand, p => changed);
                return _savecommand;
            }
        }

        private void OnSaveCommand(object parameter)
        {
            Save();
        }

		#endregion

		#region Properties

		int _schemaID;
		public int SchemaID
		{
			get { return _schemaID; }
			set
			{
				_schemaID = value;
				if (Abteilungen == null || Abteilungen.Count <= 0)
					return;

				SelectedAbteilung = Abteilungen[0];
			}
		}

		IList<Abteilung> _abteilungen;
		public IList<Abteilung> Abteilungen
		{
			get
			{
				if (_abteilungen == null)
				{
					var da = GetService<IAbteilungDataAccess>();
					var lst = da.GetAbteilungen();
					_abteilungen = lst != null ? new ObservableCollection<Abteilung>(lst) : new ObservableCollection<Abteilung>();
				}
				return _abteilungen;
			}
			set
			{
				_abteilungen = value;
				RaisePropertyChanged("Abteilungen");
			}
		}

		Abteilung _selectedAbteilung;
		public Abteilung SelectedAbteilung
		{
			get
			{
				return _selectedAbteilung;
			}
			set
			{
				if (changed)
				{
					var res = MessageBox.Show(Window.GetWindow(Parent),"Die Daten wurden geändert.\nMöchten Sie diese Speichern?","Speichern", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
					switch (res)
					{
						case MessageBoxResult.Yes:
							Save();
							break;

						case MessageBoxResult.Cancel:
							return;
					}
				}

				_selectedAbteilung = value;
				RaisePropertyChanged("SelectedAbteilung");

				if (value == null)
					return;

				var da = GetService<IDiensteDataAccess>();
				var lst = da.GetDiensteInSchema(SchemaID, value.AbteilungID);
				AddedDienste = lst != null ? new ObservableCollection<Dienst>(lst) : new ObservableCollection<Dienst>();

				lst = da.GetDienstNotInSchema(SchemaID, value.AbteilungID);
				NotAddedDienste = lst != null ? new ObservableCollection<Dienst>(lst) : new ObservableCollection<Dienst>();

				changed = false;
			}
		}


		IList<Dienst> _notAddedDienste;
		public IList<Dienst> NotAddedDienste
		{
			get { return _notAddedDienste; }
			set
			{
				_notAddedDienste = value;
				RaisePropertyChanged("NotAddedDienste");
			}
		}

		Dienst _selectedNotAddedDienst;
		public Dienst SelectedNotAddedDienst
		{
			get { return _selectedNotAddedDienst; }
			set
			{
				_selectedNotAddedDienst = value;
				RaisePropertyChanged("SelectedNotAddedDienst");
			}
		}

		IList<Dienst> _addedDienste;
		public IList<Dienst> AddedDienste
		{
			get { return _addedDienste; }
			set
			{
				_addedDienste = value;
				RaisePropertyChanged("AddedDienste");
			}
		}

		Dienst _selectedAddedDienst;
		public Dienst SelectedAddedDienst
		{
			get { return _selectedAddedDienst; }
			set
			{
				_selectedAddedDienst = value;
				RaisePropertyChanged("SelectedAddedDienst");
			}
		}

		int _einsaetzeProTag = 1;
		public int EinsaetzeProTag
		{
			get { return _einsaetzeProTag; }
			set
			{
				_einsaetzeProTag = value;
				RaisePropertyChanged("EinsaetzeProTag");
			}
		}

		#endregion
	}
}
